<?php

namespace App\Models;

use Cog\Contracts\Love\Likeable\Models\Likeable as LikeableContract;
use Cog\Laravel\Love\Likeable\Models\Traits\Likeable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;

/**
 * Class Repository
 *
 * @package App\Models
 *
 * @method Builder indexQuery()
 */
class Repository extends Model implements LikeableContract
{
    use SoftDeletes;
    use Likeable;

    const TYPE_DEFAULT = 0;//普通模式

    const TYPE_FREE = 1;//接龙模式

    const TYPE_CLOSE = 2;//不允许续写

    const TYPE_HIDDEN = 3;//隐藏模式

    protected $fillable = ['title', 'type', 'introduction', 'url', 'tags'];

    protected $appends = ['is_fork', 'likes_count', 'introduction_substring', 'introduction_html'];

    protected $casts = ['tags' => 'json'];

    protected static function boot()
    {
        parent::boot();
    }

    public function chapters()
    {
        return $this->belongsToMany(Chapter::class)->using(ChapterRepository::class)->withPivot([
            'sequence',
            'is_using',
        ])->with(['user', 'likesCounter', 'dislikesCounter']);
    }

    public function currentChapters()
    {
        return $this->chapters()->wherePivot('is_using', 1)->orderBy('chapter_repository.sequence');
    }

    public function sequence($sequence)
    {
        return $this->chapters()->wherePivot('sequence', $sequence);
    }

    public function scopeNextSequenceNumber($query, $id)
    {
        return $query->where('repository_id', $id)->max('sequence') + 1;
    }

    public function scopeIndexQuery($query)
    {
        return $query->with(['user', 'likesCounter'])->withCount([
            'currentChapters',
            'forks',
        ])->orderByDesc('sort')->where('type', '!=', static::TYPE_HIDDEN)->latest($this->getUpdatedAtColumn());
    }

    public function issues()
    {
        return $this->hasMany(Issue::class);
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }

    public function sourceRepository()
    {
        return $this->belongsTo(static::class, 'parent_id');
    }

    public function forks()
    {
        return $this->hasMany(static::class, 'parent_id');
    }

    public function pulls()
    {
        return $this->belongsToMany(Chapter::class, 'pulls')->withPivot('sequence');
    }

    public function getIsForkAttribute()
    {
        return $this->parent_id != null;
    }

    public function getIntroductionSubstringAttribute()
    {
        return Str::limit($this->introduction, 300);
    }

    public function getIntroductionHtmlAttribute()
    {
        return nl2p($this->introduction);
    }

    public function resetSequence($sequence)
    {
        $this->chapters()->wherePivot('sequence', $sequence)->wherePivot('is_using', 1)->get()->each(function ($chapter
        ) {
            $chapter->pivot->is_using = 0;
            $chapter->pivot->save();
        });
    }

    public function attachChapter(Chapter $chapter, $sequence)
    {
        $this->resetSequence($sequence);
        $this->chapters()->attach($chapter, ['sequence' => $sequence, 'is_using' => 1]);
    }

    public function switchChapter($chapter, $sequence)
    {
        $this->resetSequence($sequence);
        $this->chapters()->updateExistingPivot($chapter, ['is_using' => 1]);
    }
}
